package cn.huaguo.domain.task.service;

import cn.huaguo.domain.order.model.entity.OrderEntity;
import cn.huaguo.domain.order.model.valobj.OrderStatusVO;
import cn.huaguo.domain.order.repository.IOrderRepository;
import cn.huaguo.domain.task.model.aggragate.PublishTradeTaskAggregate;
import cn.huaguo.domain.task.model.entity.PublishTaskEntity;
import cn.huaguo.domain.task.model.entity.TaskEntity;
import cn.huaguo.domain.task.model.valobj.TaskPageQueryVO;
import cn.huaguo.domain.task.model.valobj.TaskStatusVO;
import cn.huaguo.domain.task.repository.ITaskRepository;
import cn.huaguo.domain.user.repository.IUserRepository;
import cn.huaguo.domain.wallet.model.entity.WalletEntity;
import cn.huaguo.types.common.Constants;
import cn.huaguo.types.context.BaseContext;
import cn.huaguo.types.model.PageResult;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @Description 任务服务实现类
 * @Author wangQian
 * @Date 2024/5/13
 */
@Service
public class TaskService extends AbstractTaskService {
    @Resource
    private ITaskRepository taskRepository;

    @Resource
    private IOrderRepository orderRepository;

    @Resource
    private IUserRepository userRepository;

    @Override
    protected void createPay(PublishTaskEntity publishTaskEntity) {
        OrderEntity orderEntity = orderRepository.queryOrderInfoByOrderId(publishTaskEntity.getOrderId());
        // TODO 根据订单金额 创建支付

        // 更新订单状态
        orderRepository.updateOrderStatus(publishTaskEntity.getOrderId(), OrderStatusVO.PAY_WAIT.getCode());
    }

    @Override
    protected PublishTaskEntity savePublishTaskAggregate(PublishTradeTaskAggregate publishTradeTaskAggregate) {
        return taskRepository.newTradeTask(publishTradeTaskAggregate);
    }

    /**
     * 获取任务列表（搜索+条件分页）
     *
     * @param taskPageQueryVO
     * @return
     */
    @Override
    public PageResult<TaskEntity> queryTaskList(TaskPageQueryVO taskPageQueryVO, String createUserId) {
        PageResult<TaskEntity> result = new PageResult<>();
        // 查询任务列表
        if (createUserId == null) {
            result = taskRepository.queryTaskList(taskPageQueryVO, null);
        } else if (createUserId != null) {
            result = taskRepository.queryTaskList(taskPageQueryVO, createUserId);
        } else {
            throw new IllegalArgumentException("查询条件错误，请检查");
        }
        return result;
    }

    /**
     * 根据id获取任务
     *
     * @param taskId 任务id
     * @return
     */
    @Override
    public TaskEntity getTaskById(String taskId) {
        TaskEntity taskEntity = taskRepository.getTaskById(taskId);
        return taskEntity;
    }

    /**
     * 更新任务 包含更新任务状态
     *
     * @param taskEntity
     * @return
     */
    @Override
    public Boolean updateTask(TaskEntity taskEntity) {
        return taskRepository.updateTask(taskEntity);
    }

    /**
     * 删除任务
     *
     * @param taskId
     * @return
     */
    @Override
    public void deleteTaskById(String taskId) {
        taskRepository.deleteTaskById(taskId);
    }

    /**
     * 抢任务
     *
     * @param taskEntity
     * @return
     */
    @Override
    public Boolean rushTask(TaskEntity taskEntity) {
        String userId = BaseContext.getCurrentId();
        // 获取用户接单数量
        String taskCount = getUserTaskCount(userId);
        // 扣减库存
        Boolean result = taskRepository.subtractStock(taskEntity.getTaskId());
        if (result) {
            // 库存扣减成功 延迟消费 更新数据库
            taskRepository.sendConsumerQueue(taskEntity.getTaskId());

            // 更新任务状态
            taskRepository.updateTask(TaskEntity.builder()
                    .taskId(taskEntity.getTaskId())
                    .taskStatus(TaskStatusVO.RECEIVE.getCode())
                    .takeUserId(userId)
                    .build());
            // 更新用户任务数
            upUserTaskCount(userId, taskCount);
        }
        return result;
    }

    /**
     * 确认完成任务
     *
     * @param taskId 任务id
     * @return
     */
    @Override
    public void confirmFinishTask(String taskId) {
        // 获取任务接单人id
        TaskEntity taskEntity = taskRepository.getTaskById(taskId);
        String takeUserId = taskEntity.getTakeUserId();
        OrderEntity orderEntity = orderRepository.queryOrderInfoByOrderId(taskEntity.getOrderId());

        // 构建钱包对象
        WalletEntity walletEntity = WalletEntity.builder()
                .userId(takeUserId)
                .balance(orderEntity.getOrderAmount())
                .build();

        taskRepository.confirmFinishTask(taskId, orderEntity, walletEntity);
        // 更新用户接单任务数
        downUserTaskCount(takeUserId, getUserTaskCount(takeUserId));
    }

    /**
     * 取消任务
     *
     * @param taskEntity
     * @return
     */
    @Override
    public void cancelTask(TaskEntity taskEntity) {
        // 修改任务状态为已退款 修改订单状态为已退款
        // 获取订单信息
        OrderEntity orderEntity = orderRepository.queryOrderInfoByOrderId(taskEntity.getOrderId());

        // TODO 调用退款 至发布者账户

        taskRepository.cancelTask(taskEntity, orderEntity);

        if (TaskStatusVO.RECEIVE.getCode().equals(taskEntity.getTaskStatus())) {
            // 有用户接单
            String takeUserId = taskEntity.getTakeUserId();
            // 更新用户接单任务数
            downUserTaskCount(takeUserId, getUserTaskCount(takeUserId));
        }
    }

    /**
     * 发布无交易类型任务
     *
     * @param taskEntity
     */
    @Override
    public void publishNoTradeTask(TaskEntity taskEntity) {
        taskEntity.setCreateUserId(BaseContext.getCurrentId());
        taskEntity.setTaskStatus(TaskStatusVO.PUBLISH.getCode());
        taskRepository.publishNoTradeTask(taskEntity);
    }

    public String getUserTaskCount(String openId) {
        return userRepository.getUserTaskCount(openId);
    }

    private void upUserTaskCount(String openId, String taskCount) {
        if (Constants.USER_TASK_COUNT_NONE.equals(taskCount)) {
            userRepository.updateUserTaskCount(openId, Constants.USER_TASK_COUNT_ONE);
        } else if (Constants.USER_TASK_COUNT_ONE.equals(taskCount)) {
            userRepository.updateUserTaskCount(openId, Constants.USER_TASK_COUNT_TWO);
        }
    }

    private void downUserTaskCount(String openId, String taskCount) {
        if (Constants.USER_TASK_COUNT_TWO.equals(taskCount)) {
            userRepository.updateUserTaskCount(openId, Constants.USER_TASK_COUNT_ONE);
        } else if (Constants.USER_TASK_COUNT_ONE.equals(taskCount)) {
            userRepository.updateUserTaskCount(openId, Constants.USER_TASK_COUNT_NONE);
        }
    }
}
/*
计算评分：当任务发单者确认任务完成后，打款至接单者账户，对本单任务进行评分 1-10分
评分规则：
满分10分
评分计算：(用户前一单接单的评分+账户当前分数)/2 向上取整
评分说明：
如果有一次任务被评分低于6分，封禁接单用户三天不允许接单，再次低于六分封7天 解封后将接单者评分修改至6分

用户评分表：（t_user_score）
评分（user_score）、接单封禁状态（taking_ban_status）、封禁次数（ban_count）、上次封禁时间（last_ban_time）
创建时间（create_time）、更新时间（update_time）
封禁：缓存用户接单状态 查询封禁次数并计算出封禁时长 redis封禁用户接单状态设置过期时间
解封：
任务表：
评分（task_score）
 */